home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Format 1996 April
/
MacFormat CD Edition MF36 (April 1996).iso
/
Floppy
/
CopyBeep
/
CopyBeep Source
/
copyBeep.p
next >
Wrap
Text File
|
1992-08-16
|
5KB
|
177 lines
{ CopyBeep ©1992 Gregory M. Robbins 3/92 }
{ 3/92 v 1.0 }
{ 5/92 v 1.1 plays snd resource }
UNIT CopyBeep;
INTERFACE
USES
Processes, Traps, Sound;
PROCEDURE main;
IMPLEMENTATION
PROCEDURE CloseWindowPatch (theWindowPtr: WindowPeek);
forward;
PROCEDURE ShowWindowPatch (theWindowPtr: WindowPeek);
forward;
PROCEDURE storage;
forward;
FUNCTION Gestalt (selector: OSType; VAR response: LongInt): OSErr;
{ this gestalt interface takes far fewer bytes than the standard glue }
INLINE
$4E56, $0000, { LINK A6,#0 ; make a cushy stack frame }
$202E, $0008, { MOVE.L $8(A6),D0 ; get the selector }
$A1AD, { _Gestalt }
$226E, $0004, { MOVEA.L $4(A6),A1 ; stuff the response }
$2288, { MOVE.L A0,(A1) }
$3D40, $000C, { MOVE.W D0,$C(A6) ; put the error code on the stack }
$4E5E, { UNLK A6 ; back to our previously scheduled scope }
$508F; { ADDQ.L #8,A7 ; trash them parameters }
PROCEDURE main;
VAR
toolScratchPtr: ^Ptr;
myHandle: Handle;
tempAddr: Ptr;
storagePtr: ^Ptr;
delayPtr: IntegerPtr;
delayResHandle: Handle;
sndHandle: Handle;
sndHandlePtr: LongIntPtr;
gestaltResponse: LongInt;
retCode: OSErr;
BEGIN
{ Think Pascal points toolScratch to the start of the block }
toolScratchPtr := Pointer($9CE);
myHandle := RecoverHandle(toolScratchPtr^);
{ check if Gestalt is implemented }
IF NGetTrapAddress(_GestaltDispatch, OSTrap) = NGetTrapAddress(_Unimplemented, ToolTrap) THEN
Exit(main)
ELSE
BEGIN
{ if there's no process manager cause the system version is less than 7.0, bail }
retCode := Gestalt(gestaltSystemVersion, gestaltResponse);
IF (retCode <> noErr) OR (gestaltResponse < $0700) THEN
Exit(main)
END;
{ make the init float free; it must have been loaded in the System heap and locked }
DetachResource(myHandle);
{ patch ShowWindow, $A915 }
tempAddr := Pointer(NGetTrapAddress(_ShowWindow, ToolTrap));
storagePtr := @storage;
storagePtr^ := tempAddr;
SetToolTrapAddress(LongInt(@ShowWindowPatch), _ShowWindow);
{ patch CloseWindow, $A92D }
tempAddr := Ptr(NGetTrapAddress(_CloseWindow, ToolTrap));
storagePtr := Pointer(LongInt(@storage) + 4);
storagePtr^ := tempAddr;
SetTrapAddress(LongInt(@CloseWindowPatch), _CloseWindow);
{ get delay value }
delayPtr := IntegerPtr(LongInt(@storage) + 12);
delayResHandle := Get1IndResource('DLAY', 1);
IF delayResHandle <> NIL THEN
BEGIN
delayPtr^ := IntegerPtr(delayResHandle^)^;
ReleaseResource(delayResHandle);
END
ELSE
delayPtr^ := 15;
{ get sound resource }
sndHandlePtr := LongIntPtr(LongInt(@storage) + 14);
sndHandle := Get1IndResource('snd ', 1);
sndHandlePtr^ := LongInt(sndHandle);
IF sndHandle <> NIL THEN
DetachResource(sndHandle);
END;
FUNCTION FinderIsCurrentProcess: Boolean;
VAR
thePSN: ProcessSerialNumber;
thePIR: ProcessInfoRec;
BEGIN
FinderIsCurrentProcess := FALSE;
WITH thePIR DO
BEGIN
processInfoLength := SizeOf(ProcessInfoRec);
processName := NIL;
processAppSpec := NIL
END;
IF GetCurrentProcess(thePSN) = noErr THEN
IF GetProcessInformation(thePSN, thePIR) = noErr THEN
IF thePIR.processSignature = 'MACS' THEN
FinderIsCurrentProcess := TRUE;
END;
PROCEDURE ShowWindowPatch (theWindowPtr: WindowPeek);
PROCEDURE ExitPatch (PP: longint);
INLINE
$205F, { MOVEA.L (A7)+,A0 }
$265F, { MOVEA.L (A7)+,A3 ; compiled code preserved A3 }
$4E5E, { UNLK A6 }
$4ED0; { JMP (A0) }
VAR
tempLongIntPtr: LongIntPtr;
BEGIN
IF theWindowPtr^.windowKind = $14 THEN
IF theWindowPtr^.goAwayFlag = FALSE THEN
IF FinderIsCurrentProcess THEN
BEGIN { store current tick count }
tempLongIntPtr := LongIntPtr(LongInt(@storage) + 8);
tempLongIntPtr^ := TickCount;
END;
ExitPatch(LongIntPtr(@storage)^);
END;
PROCEDURE CloseWindowPatch (theWindowPtr: WindowPeek);
PROCEDURE ExitPatch (PP: longint);
INLINE
$205F, { MOVEA.L (A7)+,A0 }
$4E5E, { UNLK A6 }
$4ED0; { JMP (A0) }
VAR
retCode: OSErr;
BEGIN
IF theWindowPtr^.windowKind = $14 THEN
IF theWindowPtr^.goAwayFlag = FALSE THEN
IF FinderIsCurrentProcess THEN
IF LongIntPtr(LongInt(@storage) + 8)^ + 60 * IntegerPtr(LongInt(@storage) + 12)^ < TickCount THEN { been more than 15 secs }
IF LongIntPtr(LongInt(@storage) + 8)^ + 216000 > TickCount THEN { forget it after an hour }
BEGIN
IF LongIntPtr(LongInt(@storage) + 14)^ <> LongInt(NIL) THEN { play the sound }
retCode := SndPlay(NIL, Handle(LongIntPtr(LongInt(@storage) + 14)^), false)
ELSE { no sound resource, so just beep }
SysBeep(20);
END;
ExitPatch(LongIntPtr(LongInt(@storage) + 4)^)
END;
PROCEDURE storage;
{ storage: ShowWindow addr; +4: CloseWindow addr; +8: tickcount at ShowWindow break; }
{ +12: min delay in seconds; +14: sndHandle }
PROCEDURE nops;
INLINE
$4E71, $4E71, $4E71, $4E71, $4E71, $4E71;
BEGIN
nops
END;
END.